package com.touni.javassist;

import javassist.*;

import java.lang.reflect.InvocationTargetException;

/**
 * Created by
 *  使用javassist动态创建一个类，这个类实现了HelloOne的接口
 *
 *  javassist的特殊符号：    javassist中不会对类型对错进行判断，书写时候注意
 *     $0代表的是this  $1 代表的是第一个参数  $n代表的是第n个参数（n不包括0）
 *     $_ 返回值
 *
 *
 *
 *
 * @author touni
 * @date 2019/4/30
 * @time 12:52
 */
public class FirstJavassist {

    public static void main(String[] args) throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //获取一个pool
        ClassPool pool = new ClassPool(true);
        //插入类的路径
        pool.insertClassPath(new LoaderClassPath(FirstJavassist.class.getClassLoader()));
        //通过make方法构建一个class对象
        CtClass ctClass = pool.makeClass("NewClass");
        //使这个类实现一个接口
        ctClass.addInterface(pool.get(HelloOne.class.getName()));
        //补充这个类，实现这个接口的方法
        CtClass returnType = pool.get(void.class.getName());
        String mname = "sayHello";
        CtClass[] parameters = new CtClass[]{pool.get(String.class.getName())};
                                        //返回值类型  方法名称  参数     添加到的ctclass
        CtMethod ctMethod = new CtMethod(returnType,mname,parameters,ctClass);
        //添加方法里面的代码          $0代表的是this  $1 代表的是第一个参数  $n代表的是第n个参数（n不包括0）
        String src = "{System.out.println(\"Hello\"+$1);}";
        ctMethod.setBody(src);
        //给这个类添加相应的方法
        ctClass.addMethod(ctMethod);
        Class cla = ctClass.toClass();
        HelloOne hello = (HelloOne) cla.newInstance();
        hello.sayHello("德玛西亚");


        //以下是没有继承接口  使用反射来执行方法的
        /*Object instance = cla.newInstance();
        Method sayHello = cla.getMethod("sayHello", String.class);
        sayHello.invoke(instance,"啦啦啦");*/


    }



    public interface HelloOne{
        public void sayHello(String para);
    }





}
